package com.jbp.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jbp.dao.HamsterDao;
import com.jbp.domin.WhacMoleReq;
import com.jbp.exception.RRException;
import com.jbp.model.*;
import com.jbp.redis.RedisConfigService;
import com.jbp.service.*;
import com.jbp.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
public class HamsterServiceImpl extends ServiceImpl<HamsterDao, Hamster> implements HamsterService {

    @Autowired
    private HamsterKindService hamsterKindService;

    @Autowired
    private HammerTypeService hammerTypeService;

    @Autowired
    private WalletService walletService;

    @Autowired
    private RoomService roomService;

    @Autowired
    private RankProportionService rankProportionService;

    @Autowired
    private RedisConfigService redisConfigService;

    @Autowired
    private WalletRecordService walletRecordService;

    @Autowired
    private HamsterRecordService hamsterRecordService;

    @Autowired
    private PushService pushService;

    @Autowired
    private GiftService giftService;

    @Autowired
    private HamsterProbabilityService hamsterProbabilityService;

    @Autowired
    private PropertyService propertyService;

    /**
     * 打地鼠业务逻辑处理
     * @param whacMoleReq
     * @return
     */
    @Transactional
    @Override
    public R whacMole(WhacMoleReq whacMoleReq) {

        String hamsterKind = whacMoleReq.getHamsterKind();//地鼠种类标识：塑料头盔地鼠1；木头盔地鼠2；银头盔地鼠3；金头盔地鼠4；皇冠5
        String hammerType = whacMoleReq.getHammerType();//锤子种类
        Integer userId = whacMoleReq.getUserId();
        Integer roomId = whacMoleReq.getRoomId();

        //本次抽奖需要花费的心钻   hammerType.getPoints();
        boolean aa = redisConfigService.exists("point"+hammerType);
        int xinZuan = redisConfigService.getInt("point"+hammerType);
        if(xinZuan == 0){
            HammerType hammerTypeTemp = hammerTypeService.getOne(new QueryWrapper<HammerType>().eq("hammer_type", hammerType));
            xinZuan = hammerTypeTemp.getPoints();
            redisConfigService.set("point"+hammerType, xinZuan);
            //return R.error("锤子对应积分缓存不存在，请到管理后台添加或编辑锤子种类");
        }
        int multiplier = redisConfigService.getInt("multiplier"+hamsterKind);
        if(multiplier == 0){
            QueryWrapper<HamsterKind> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("type",hamsterKind);
            HamsterKind hamsterKindTemp = hamsterKindService.getOne(new QueryWrapper<HamsterKind>().eq("type", hamsterKind));
            multiplier =  hamsterKindTemp.getMultiplier();
            redisConfigService.set("multiplier"+hamsterKind, multiplier);
//            return R.error("地鼠种类对应倍率缓存不存在，请到管理后台添加或编辑地鼠种类");
        }
        int appearanceProb = redisConfigService.getInt("appearanceProb"+hammerType+hamsterKind);
        if(appearanceProb == 0){
            QueryWrapper<HamsterProbability> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("hammer_type",hammerType);
            queryWrapper.eq("hamster_type",hamsterKind);
            HamsterProbability hamsterProbability = hamsterProbabilityService.getOne(queryWrapper);
            appearanceProb = hamsterProbability.getAppearanceProb();
//            return R.error("地鼠种类对应概率不存在，请到管理后台添加或编辑地鼠种类");
        }

        //检查余额
        checkWallet(userId, xinZuan);

        int TOTAL_DRAWS = 1000;//总次数
        List<Object> winningPositions = redisConfigService.lRange("winningPositions"+hammerType+hamsterKind, 0, -1);
        if (null == winningPositions || winningPositions.isEmpty()) {
            List<Integer> drawNumbers = IntStream.rangeClosed(1, TOTAL_DRAWS)
                    .boxed()
                    .collect(Collectors.toList());
            Collections.shuffle(drawNumbers);
            // 取前5个作为中奖位置
            List<Integer> winningPositionTemp = drawNumbers.subList(0, appearanceProb);
//            redisConfigService.lPush("winningPositions"+hamsterKindId, winningPositionTemp);
            for (Integer num : winningPositionTemp) {
                redisConfigService.lPush("winningPositions"+hammerType+hamsterKind, num.toString());
            }
        }
        int counts = redisConfigService.getInt("counts"+hamsterKind+"_"+hammerType);
        counts = counts + 1;
        redisConfigService.set("counts"+hamsterKind+"_"+hammerType, counts);
        if (counts > TOTAL_DRAWS){
            redisConfigService.remove("winningPositions"+hammerType+hamsterKind);
            redisConfigService.remove("counts"+hamsterKind+"_"+hammerType);
            counts = 1;
            redisConfigService.set("counts"+hamsterKind+"_"+hammerType, counts);
            //重新生成中奖数字
            // 生成1-1000的列表并打乱顺序
            List<Integer> drawNumbers = IntStream.rangeClosed(1, TOTAL_DRAWS)
                    .boxed()
                    .collect(Collectors.toList());
            Collections.shuffle(drawNumbers);
            // 取前5个作为中奖位置
            List<Integer> winningPositionTemp = drawNumbers.subList(0, appearanceProb);
//            redisConfigService.lPush("winningPositions"+hamsterKindId, winningPositionTemp);
            for (Integer num : winningPositionTemp) {
                redisConfigService.lPush("winningPositions"+hammerType+hamsterKind, num.toString());
            }
            winningPositions = redisConfigService.lRange("winningPositions"+hammerType+hamsterKind, 0, -1);
        }

        int result = 0;
//        int numbers = 0;
        if (winningPositions.contains(String.valueOf(counts))) {//打死地鼠
//            System.out.println("counts_"+hammerType+"_"+hamsterKind+",第" + counts + "次：中！");
            //打死地鼠后返还对应奖品
            //中奖返还 公式 锤子积分X中奖倍率X地鼠卷   地鼠卷1钻石
            //礼物价值
            int coin =  redisConfigService.getInt("coin");
            if (coin == 0){
                /*Gift tempGift = giftService.getOne(Wrappers.<Gift>lambdaQuery()
                        .eq(Gift::getName,"地鼠券"));
                coin = tempGift.getCoin();*/
                String hamster_coupon = propertyService.getV("hamster_coupon");//地鼠券
                redisConfigService.set("coin", Integer.valueOf(hamster_coupon));
            }

            result = xinZuan * multiplier * coin;
//            numbers = -result;

            //钱包金额变更
            WalletRecord walletRecord = new WalletRecord();
            Wallet wallet = walletService.getByUserId(userId);
            /*walletRecord.setBeforeBalance(wallet.getScore());
            wallet.setScore(wallet.getScore().add(new BigDecimal(result)));
            walletRecord.setAfterBalance(wallet.getScore());
            walletRecord.setCoinType("score");
            walletRecord.setChangeBalance(new BigDecimal(result));*/

            walletRecord.setBeforeBalance(wallet.getXinzuan());
            wallet.setXinzuan(wallet.getXinzuan().add(new BigDecimal(result)));
            walletRecord.setAfterBalance(wallet.getXinzuan());
            walletRecord.setCoinType("xinzuan");
            walletRecord.setChangeBalance(new BigDecimal(result));

            walletRecord.setAddType("add");
            walletRecord.setUserId(wallet.getUserId());
            walletRecord.setOperationType("lucky");
            walletRecord.setCreateTime(new Date());
            walletRecordService.save(walletRecord);
            walletService.updateWithLock(wallet);

            //打死地鼠发消息
            pushService.hamsterLucky(userId, result, whacMoleReq);

        }
        /*else {//未打死地鼠
            System.out.println("counts_"+hammerType+"_"+hamsterKind+",第" + counts + "次：未中");
            //未打死消耗积分不返还奖品
            numbers = xinZuan;

        }*/

        //房主提成5%积分
        String roomerRate = propertyService.getV("room_rate");//地鼠房主收入比例
        BigDecimal roomOwner = new BigDecimal(xinZuan).multiply(new BigDecimal(roomerRate));
        Room rom = roomService.getOne(new QueryWrapper<Room>().eq("id",roomId));
        if (rom != null) {
            Integer roomUserId = rom.getUserId();
            //钱包金额变更
            WalletRecord walletRecord = new WalletRecord();
            Wallet wallet = walletService.getByUserId(roomUserId);
            /*walletRecord.setBeforeBalance(wallet.getScore());
            wallet.setScore(wallet.getScore().add(roomOwner));
            walletRecord.setAfterBalance(wallet.getScore());
            walletRecord.setCoinType("score");
            walletRecord.setChangeBalance(roomOwner);*/

            walletRecord.setBeforeBalance(wallet.getXinzuan());
            wallet.setXinzuan(wallet.getXinzuan().add(roomOwner));
            walletRecord.setAfterBalance(wallet.getXinzuan());
            walletRecord.setCoinType("xinzuan");
            walletRecord.setChangeBalance(roomOwner);


            walletRecord.setAddType("add");
            walletRecord.setUserId(wallet.getUserId());
            walletRecord.setOperationType("lsfc");
            walletRecord.setCreateTime(new Date());
            walletRecordService.save(walletRecord);
            walletService.updateWithLock(wallet);
        }

        //钱包金额变更
        WalletRecord walletRecord = new WalletRecord();
        Wallet wallet = walletService.getByUserId(userId);

        //钱包金额变更
        walletRecord.setBeforeBalance(wallet.getXinzuan());
        wallet.setXinzuan(wallet.getXinzuan().subtract(new BigDecimal(xinZuan)));
        walletRecord.setAfterBalance(wallet.getXinzuan());
        walletRecord.setCoinType("xinzuan");
        walletRecord.setChangeBalance(new BigDecimal(xinZuan));

        walletRecord.setAddType("sub");
        walletRecord.setUserId(wallet.getUserId());
        walletRecord.setOperationType("lucky");
        walletRecord.setCreateTime(new Date());
        walletRecordService.save(walletRecord);
        walletService.updateWithLock(wallet);

        //百万奖池金额处理
        rankProportionService.addPrizePoolAmount(walletRecord.getChangeBalance());

        HamsterRecord  hamsterRecord = new HamsterRecord();
        hamsterRecord.setHamsterKind(hamsterKind);
        hamsterRecord.setHammerType(hammerType);
        hamsterRecord.setRoomId(roomId);
        hamsterRecord.setUserId(userId);
        if (result > 0){
            hamsterRecord.setIncome(result);
        }else {
            hamsterRecord.setIncome(0);
        }
        hamsterRecord.setPay(xinZuan);
        hamsterRecord.setCreateTime(new Date());
        if (result > 0){
            hamsterRecord.setMaxPrice(result);
        }else {
            hamsterRecord.setMaxPrice(0);
        }

        hamsterRecordService.save(hamsterRecord);
        Map<String, Object> map = new HashMap<>();
        if (result > 0){//打死，中奖
            map.put("hit", "yes");
            map.put("lucks", result);
        }else {
            map.put("hit", "no");
        }
//        map.put("hamsterKindId", hamsterKindId);//地鼠种类id

        return R.ok().put("data", map);
    }


    /** 检查钱包余额 */
    private void checkWallet(Integer userId, int xinZuan) {
        Wallet wallet = walletService.getByUserId(userId);
        if ((wallet.getScore().compareTo(new BigDecimal(xinZuan)))<0
                && (wallet.getXinzuan().compareTo(new BigDecimal(xinZuan)))<0){
            throw  new RRException("钱包余额不足");
        }
    }





}
